Skip to content

feat(settings): Security section to manage 2FA in-app - #23

Merged
Lingz450 merged 1 commit into
mainfrom
feat/security-settings
Jun 24, 2026
Merged

feat(settings): Security section to manage 2FA in-app#23
Lingz450 merged 1 commit into
mainfrom
feat/security-settings

Conversation

@Lingz450

Copy link
Copy Markdown
Collaborator

Summary

Adds a Security tab to Settings so a signed-in user can set up and manage two-factor authentication without going through the at-login challenge. This is what the flag-off-first rollout needs - you can now enrol from Settings before turning on PB_REQUIRE_2FA.

Backend (session-authenticated)

Distinct from the at-login enroll/verify (which use a challenge token); these use the normal session bearer:

  • POST /auth/2fa/setup - provision a pending secret + otpauth:// URI
  • POST /auth/2fa/activate - confirm a code, enable, return one-time recovery codes
  • POST /auth/2fa/disable - turn off; blocked while PB_REQUIRE_2FA is on, and requires a current code
  • POST /auth/2fa/recovery-codes - regenerate recovery codes (requires a current code)

Disable and regenerate require a live TOTP (recovery codes are not accepted there) so a hijacked session can't weaken the account. All share the per-account lockout.

Frontend

  • lib/auth/api.ts: get2faStatus / setup2fa / activate2fa / disable2fa / regenerateRecoveryCodes.
  • New Security settings section (SecuritySection.tsx): on/off status, QR-less enrollment (authenticator deep link + copyable manual key), one-time recovery-codes display, regenerate, and turn-off (hidden when 2FA is mandatory).

Verification

  • Backend: ruff, mypy (132 files), red-team eval (0 failures), 12 test_2fa.py tests (5 new for the session endpoints) + auth tests pass.
  • Frontend: typecheck, lint, build, 132 web tests pass.

Depends on the 2FA backend from #22 (already merged).

🤖 Generated with Claude Code

Lets a signed-in user set up, manage, and (when not mandatory) turn off
two-factor without going through the at-login challenge. Needed for the
flag-off-first rollout: you can now enrol from Settings before enforcing.

Backend (session-authenticated, distinct from the challenge-token enroll/verify):
- POST /auth/2fa/setup     - provision a pending secret + otpauth URI
- POST /auth/2fa/activate  - confirm a code, enable, return recovery codes
- POST /auth/2fa/disable   - turn off (blocked while PB_REQUIRE_2FA; needs a code)
- POST /auth/2fa/recovery-codes - regenerate (needs a code)
Disable/regenerate require a live TOTP (recovery codes not accepted) so a
hijacked session can't weaken the account; all share the per-account lockout.

Frontend:
- lib/auth/api.ts: get2faStatus/setup2fa/activate2fa/disable2fa/regenerate.
- New Settings "Security" tab (SecuritySection): status, QR-less enrollment
  (otpauth deep link + manual key), one-time recovery codes, regenerate, and
  turn-off (hidden when 2FA is required).

Gates: ruff, mypy (132 files), red-team eval (0), 12 2FA tests (5 new) + auth
tests; web typecheck/lint/build + 132 web tests all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
petrobrain Ready Ready Preview, Comment Jun 24, 2026 2:17pm

@Lingz450
Lingz450 merged commit f074ca7 into main Jun 24, 2026
7 checks passed
@Lingz450
Lingz450 deleted the feat/security-settings branch June 24, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant